function fyWebsocket(conf) {
    let websocket = null;
    let heartbeatIntervalNum = 0;
    // 记录重连定时器的编号
    let reConnIntervalNum = 0;
    // 记录心跳间隔
    let heartbeatInterval = 9000;
    // 记录下次定时间隔（毫秒），暂定为重连5次，每次在上一次基础上 * 3
    let reConnTime = 10000;
    // 记录上次正常的心跳时间，如果事件差相差了9s则认为连接中断
    let heartbeatTime = new Date().getTime();

    function init() {
        resetHeartbeatTime();
        if ("WebSocket" in window) {
            console.log("开始连接");
            if (null != websocket) {
                console.log("已经连接，无需重新初始化连接");
                return;
            }
            console.log("开始连接");
            websocket = new WebSocket(conf.url);
            websocket.onopen = function () {
                reConnTime = 3000;
                window.clearInterval(reConnIntervalNum);
                console.log("连接成功");
                heartbeat();
            }

            websocket.onclose = function () {
                websocket = null;
                console.log("退出连接");
                reconnect();
            }

            websocket.onmessage = function (event) {
                receiveMsg(event.data);
            }

            websocket.onerror = function () {
                websocket = null;
                console.log("连接出错");
                reconnect();
            }

            window.onbeforeunload = function () {
                websocket.close();
            }
        } else {
            console.log("您的浏览器不支持WebSocket");
        }
    };
    init();

    /**
     * 接收消息，心跳则直接重置
     * @param body  消息
     */
    function receiveMsg(msg) {
        resetHeartbeatTime();
        console.log("收到消息：" + msg);
        /**
         * 1 - 点对点消息 - 单聊
         * 2 - 群组消息 - 群聊
         * 3 - 广播消息 - 给所有人发
         * 4 - 心跳消息 - 定时检测
         * 5 - 通知消息 - 转发不保存
         */
        const message = JSON.parse(msg);
        switch (message.type) {
            case 2:
            case 1:
                showMsg(message);
                break;
            case 5:
                $("#sysMsg").html(message.body);
                initData();
                break;
            case 3:
                $("#sysMsg").html(message.body);
                break;
            case 4:
                // 只有是后台主动发起的心跳才回应
                if ("SYS" == message.body) {
                    send({body: "OK", type: 4});
                }
                break;
        }
    };

    /**
     * 发送消息
     * @param from  消息发送者
     * @param to    消息接受者
     * @param body  消息
     * @param type  消息类型：1、单个消息；2、群发消息，此时to为群组；3、广播消息
     */
    this.sendMsg = function (from, to, body, type) {
        var msg = {from: from, to: to, body: body, type: type};
        send(msg);
    };

    /**
     * 心跳
     */
    function heartbeat() {
        console.log("执行心跳");
        if (0 != heartbeatIntervalNum) return;
        if (!websocket) return;
        heartbeatIntervalNum = window.setInterval(function () {
            // 判断连接是否断开，连续1分钟都没有收到心跳，则设置失败
            if (new Date().getTime() - heartbeatTime > 60000) {
                console.log("连续1分钟没有收到心跳，连接已断开");
                websocket = null;
                cleanInterval();
                // TODO 跳转到登录页面
                window.location.href = "/";
                return;
            }
            console.log(new Date().getTime() - heartbeatTime);
            heartbeatTime += heartbeatInterval;
            console.log("发送心跳");
            send({body: "CLIENT", type: 4});
        }, heartbeatInterval);
    }

    function send(msg) {
        try {
            websocket.send(JSON.stringify(msg));
        } catch (e) {
            // 消息无法发送时，增加心跳时间，也就是按心跳未发送来处理
            heartbeatTime -= heartbeatInterval;
            console.error("消息发送失败")
        }
    }

    function resetHeartbeatTime() {
        heartbeatTime = new Date().getTime();
    }

    function reconnect() {
        if (0 != reConnIntervalNum) return;
        console.log("尝试重连=" + reConnTime);
        cleanInterval();
        reConnTime = reConnTime * 3;
        reConnIntervalNum = window.setInterval(init, reConnTime);
    }

    function cleanInterval() {
        window.clearInterval(heartbeatIntervalNum);
        window.clearInterval(reConnIntervalNum);
        heartbeatIntervalNum = 0;
        reConnIntervalNum = 0;
    }
}

function showMsg() {}